package scau.hotel.hotel_sys.security.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import scau.hotel.hotel_model.redis.RedisCache;
import scau.hotel.hotel_sys.entity.SysRole;
import scau.hotel.hotel_sys.entity.SysUser;
import scau.hotel.hotel_sys.security.domain.LoginUser;
import scau.hotel.hotel_sys.service.ISysUserService;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * Authentication用户认证服务类
 */
@Service("userDetailsServiceImpl")
public class UserDetailsServiceImpl implements UserDetailsService {
    @Autowired
    ISysUserService sysUserService;

    @Resource
    private RedisCache redisCache;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        List<GrantedAuthority> authorities = new ArrayList<>();
        GrantedAuthority authority;

        SysUser sysUser = sysUserService.queryByUsername(username);
        // 是否找到用户，未找到抛出异常
        if (sysUser == null) {
            throw new UsernameNotFoundException("未找到用户");
        }
        List<SysRole> roles = sysUser.getRoles();
        // 是否获得权限集合
        if(roles != null){
            for(SysRole role : roles){
                authority = new SimpleGrantedAuthority(role.getCode());
                authorities.add(authority);
            }
        }

        // redis缓存需设置唯一值，建议uuid
        String userKey = username;

        // 更新缓存有效期时间
        long loginTime = System.currentTimeMillis();
        int addExpireTime = 30*60*1000; //设置loginUser的缓存过期时间为30分钟。建议与token过期时间相等或者小于token过期时间。
//        int addExpireTime = 60*1000; //设置loginUser的缓存过期时间为30分钟。建议与token过期时间相等或者小于token过期时间。
        long expireTime = loginTime + addExpireTime;

        LoginUser loginUser = new LoginUser(sysUser.getId(),sysUser.getUsername(), sysUser.getPassword(), sysUser, loginTime, expireTime, authorities);

        redisCache.setCacheObject(userKey, loginUser, addExpireTime, TimeUnit.MINUTES);

        // 创建登录用户对象进行验证
        return loginUser;
    }
}